<?php
/**
 * ClassName: PrescriptService
 * Description: 处方service
 * @Author 周昌
 * @Create 2023/11/30 10:54
 */

namespace service\admin;


use Exception;
use libs\Tool;
use model\ArchivesModel;
use model\CardLogModel;
use model\MedicineModel;
use model\PaymentLog;
use model\PaymentLogModel;
use model\PrescriptMedicineModel;
use model\PrescriptModel;
use model\WaitModel;
use service\admin\MedicineService;
use service\BaseService;
use think\Db;

class PrescriptService extends BaseService
{
    protected static $model='model\PrescriptModel';
    public static $prescript_status=[0=>'待取药',1=>'已取药',2=>'已取消'];//处方状态
    public static $prescript_status_index=['pend'=>0,'has_been_take'=>1,'cancel'=>2];//处方状态码
    public static $prescript_payment=[0=>'待支付',1=>'已支付'];//支付状态
    public static $prescript_payment_index=['to_be_pay'=>0,'paid'=>1];//支付状态
    public static $pay_type=[0=>'卡支付',1=>'线下支付'];
    public static $pay_type_index=['card_pay'=>0,'offline_pay'=>1];

    //处方状态下拉选择
    public static function prescriptStatusSelect($key=0)
    {
        static $prescript_status_select=[];
        if(empty($prescript_status_select)){
            foreach (self::$prescript_status as $k=>$v){
                if($k>=$key){
                    $row=[];
                    $row['id']=$k;
                    $row['name']=$v;
                    $prescript_status_select[]=$row;
                }
            }
            array_unshift($prescript_status_select,['id'=>'','name'=>'-----请选择-----']);
        }
        return $prescript_status_select;
    }
    //处方支付类型下拉选择
    public static function prescriptPayTypeSelect()
    {
        static $prescript_pay_type_select=[];
        if(empty($prescript_pay_type_select)){
            foreach (self::$pay_type as $k=>$v){
                $row=[];
                $row['id']=$k;
                $row['name']=$v;
                $prescript_pay_type_select[]=$row;
            }
            array_unshift($prescript_pay_type_select,['id'=>'','name'=>'-----请选择-----']);
        }
        return $prescript_pay_type_select;
    }
    //获取处方详情
    public static function prescriptInfo($prescript_id)
    {
        $info=self::$model::where('id',$prescript_id)->with(['medicine'=>function($q){
            $q->field('*');
        }])->find();
        if($info){
            $info=$info->toArray();
            $info['num']=self::prescriptNum($info['id']);
            $info['doctor_name']=AdminService::getNameByKey($info['admin_id'],['hospital_id'=>$info['hospital_id']],'id,group_name');
        }else{
            $info=[];
        }

        return $info;
    }
    //根据处方id生成处方编号
    public static function prescriptNum($id)
    {
        $num=$id;
        if($id<10000){
            $num=sprintf('%05d',$id);
        }
        return $num;
    }
    //处方支付状态下拉选择
    public static function prescriptPaymentSelect()
    {
        static $prescript_payment_select=[];
        if(empty($prescript_payment_select)){
            foreach (self::$prescript_payment as $k=>$v){
                $row=[];
                $row['id']=$k;
                $row['name']=$v;
                $prescript_payment_select[]=$row;
            }
            array_unshift($prescript_payment_select,['id'=>'','name'=>'-----请选择-----']);
        }
        return $prescript_payment_select;
    }
    //添加
    public static function addInfo($data,$wait_id)
    {
       if(empty($data)||empty(array_filter($data['name']))){
           return Tool::Error('请添加药品');
       }
        //处方主表数据
        $insert=WaitModel::getInfo(['id'=>$wait_id],'hospital_id,archives_id,admin_id,case_id,name as realname,sex');
        $insert['sex']=MemberService::$sex[$insert['sex']];
        if(isset($data['age'])){
            $insert['age']=$data['age'];
        }
        $insert['admin_id']=self::getAdminInfo()['id'];//就诊医生id
        $insert['admin_name']=self::getAdminInfo()['group_name'];//就诊医生姓名
        $insert['doctor_advice']=$data['doctor_advice'];
        $insert['total_price']=$data['total_price']?number_format($data['total_price'], 2, '.', ''):0;
        $insert['status']=0;
        $insert['payment_status']=0;
        $insert['addtime']=time();

        //处方副表数据-将处方药品各项数据整理为一个二维关联数据
        $medicine_insert=[];
        foreach ($data['name'] as $k=>$v){
//            $name=explode('-',$v);
//            $name=end($name);
            $row=[
                'name'=>$v,
                'medicine_id'=>$data['id'][$k] ?? 0,
                'unit'=> $data['unit'][$k] ?? '',
                'quantity'=> $data['quantity'][$k] ?? 0,
                'price'=> $data['price'][$k] ?? 0,
                'subtotal'=> $data['subtotal'][$k] ?? 0,
                'addtime'=>time(),
            ];
            $medicine_insert[]=$row;
        }

        Db::startTrans();
        try {
            //批量更新库存 减库存
            $result=MedicineService::updateMoreInventory($data['id'],$data['quantity'],0);
            if($result['code']==0){
                Db::rollback();
                return Tool::Error($result['msg']);
            }
            $id=PrescriptModel::insertInfo($insert);
            if(!$id){
                Db::rollback();
                return Tool::Error('保存失败');
            }
            $medicine_insert=array_map(function ($value)use ($insert,$id){
                $value['prescript_id']=$id;
                return $value;
            },$medicine_insert);
            $res=PrescriptMedicineModel::insertMore($medicine_insert);
            if(!$res){
                Db::rollback();
                return Tool::Error('处方药品记录保存失败');
            }

            Db::commit();
            return Tool::Success();
        }catch (Exception $exception){
            Db::rollback();
            return Tool::Error($exception->getMessage());
        }

    }
    //修改
    public static function editInfo($data,$id)
    {
       if(empty($data)||empty(array_filter($data['name']))){
           return Tool::Error('请添加药品');
       }
        //处方主表数据
        if(isset($data['age'])){
            $insert['age']=$data['age'];
        }
        $insert['address']=$data['address']??'';
        $insert['doctor_advice']=$data['doctor_advice'];
        $insert['total_price']=$data['total_price']?:0;

        //处方副表数据-将处方药品各项数据整理为一个二维关联数据
        $medicine_insert=[];
        foreach ($data['name'] as $k=>$v){
            $row=[
                'prescript_id'=>$id,
                'name'=>$v,
                'medicine_id'=>$data['id'][$k] ?? 0,
                'unit'=> $data['unit'][$k] ?? '',
                'quantity'=> $data['quantity'][$k] ?? 0,
                'price'=> $data['price'][$k] ?? 0,
                'subtotal'=> $data['subtotal'][$k] ?? 0,
                'addtime'=>time(),
            ];
            $medicine_insert[]=$row;
        }
        Db::startTrans();
        try {
            //修改之前的数据
            $old=PrescriptMedicineModel::getListColumn(['prescript_id'=>$id],'id,medicine_id,quantity');
            //库存操作,释放修改之前药品的库存，扣除修改之后药品库存
            //加
            if($old){
                $old_medicine_ids=array_column($old,'medicine_id');
                $old_quantity=array_column($old,'quantity');
                $old_res=MedicineService::updateMoreInventory($old_medicine_ids,$old_quantity,1);
                if($old_res['code']==0){
                    Db::rollback();
                    return Tool::Error($old_res['msg']);
                }
            }
            //减
            $new_res=MedicineService::updateMoreInventory($data['id'],$data['quantity'],0);
            if($new_res['code']==0){
                Db::rollback();
                return Tool::Error($new_res['msg']);
            }
            $result=PrescriptModel::updateInfo(['id'=>$id],$insert);
            $del=PrescriptMedicineModel::delInfo(['prescript_id'=>$id]);
            $res=PrescriptMedicineModel::insertMore($medicine_insert);
            if(!$result||!$res||!$del){
                Db::rollback();
                return Tool::Error();
            }
            Db::commit();
            return Tool::Success();
        }catch (Exception $exception){
            Db::rollback();
            return Tool::Error($exception->getMessage());
        }

    }
    //处方 取药并支付
    public static function takeAndPay($id,$data)
    {
        $info=self::$model::getInfo(['id'=>$id]);
//        $member_id=ArchivesModel::getValue(['id'=>$info['archives_id']],'member_id');
        $archives_info=ArchivesModel::getInfo(['id'=>$info['archives_id']],'member_id,member_info_id,name');

        Db::startTrans();
        try{
            //更新处方表
            $data['payment_status']=self::$prescript_payment_index['paid'];
            $res=self::edit($id,$data);
            if($res['code']==0){
                Db::rollback();
                return Tool::Error('处方更新失败');
            }
            //支付添加记录
            if($data['pay_type']){
                //线下支付
                $insert=[
                    'pay_type'=>CardLogService::$log_pay_type_index['offline_pay'],
                    'member_id'=>$archives_info['member_id'],
                    'member_info_id'=>$archives_info['member_info_id'],
                    'money'=>$info['total_price'],
                    'pay_money'=>$info['total_price'],
                ];
                $card_log=CardLogService::addCardLog(CardLogService::$card_log_type_index['take_medicine'],$insert,$info['case_id']);
                if($card_log['code']==0){
                    Db::rollback();
                    return Tool::Error('线下支付失败');
                }
                //添加线下支付消息
                $message_res=MessageService::addMessage($archives_info['member_id'],MessageService::$message_type_index['consume'],$info['total_price'],null,null);
                if($message_res['code']==0){
                    Db::rollback();
                    return Tool::Error('线下支付消息添加失败');
                }
            }else{
                //卡支付
                $log_insert=[
                    'type'=>CardLogService::$card_log_type_index['take_medicine'],
                    'pay_type'=>CardLogService::$log_pay_type_index['card_pay'],
                    'member_id'=>$archives_info['member_id'],
                    'member_info_id'=>$archives_info['member_info_id'],
                    'card_id'=>$data['card_id'],
                    'money'=>$info['total_price'],
                    'case_id'=>$info['case_id'],
                ];
                //卡消费+卡消费记录
               $consume=CardService::cardConsume(['id'=>$data['card_id']],$info['total_price'],$log_insert);
                if($consume['code']==0){
                    Db::rollback();
                    return Tool::Error('会员卡支付失败');
                }
//               $card_log=CardLogService::addCardLog(CardLogService::$card_log_type_index['take_medicine'],$log_insert,$info['case_id']);
//                if($card_log['code']==0||$consume['code']==0){
//                    Db::rollback();
//                    return Tool::Error('会员卡支付失败');
//                }
                //卡支付消息
                $message_res=MessageService::addMessage($archives_info['member_id'],MessageService::$message_type_index['consume'],$info['total_price'],$data['card_id'],null);
                if($message_res['code']==0){
                    Db::rollback();
                    return Tool::Error('卡支付消息添加失败');
                }
            }
            Db::commit();
            return Tool::Success();

        }catch (\Exception $exception){
            Db::rollback();
            return Tool::Error();
        }
    }

    //处方 取药 取消 并归还库存
    public static function cancel($id)
    {
         Db::startTrans();
        try {
            //更新处方状态
            $edit_res=self::edit($id,['status'=>self::$prescript_status_index['cancel']]);
            if($edit_res['code']==0){
                Db::rollback();
                return Tool::Error('处方更新状态失败');
            }
            //归还库存
            $medicines=PrescriptMedicineModel::getList(['prescript_id'=>$id],'medicine_id,quantity');
            $medicine_ids=array_column($medicines,'medicine_id');
            $quantitys=array_column($medicines,'quantity');
            $inventory_res=MedicineService::updateMoreInventory($medicine_ids,$quantitys,1);
            if($inventory_res['code']==0){
                Db::rollback();
                return Tool::Error('处方归还药品库存失败');
            }
            Db::commit();
            return Tool::Success('处方取消成功');
        }catch (\Exception $exception){
            Db::rollback();
            return Tool::Error($exception->getMessage());
        }
    }

    //列表数据
    public static function getAjaxData($where)
    {
        $table = self::$model::order(['status'=>'asc','payment_status'=>'asc','id'=>'desc']);
        return self::tableJsonData($table, $where, function ($data){
            $data['status_name']=self::$prescript_status[$data['status']];
            $data['num']=self::prescriptNum($data['id']);
            $data['payment']=self::$prescript_payment[$data['payment_status']];
            $data['take_away_time']=$data['take_away_time']??'';
            $data['hospital_name'] = $data['hospital_id']?HospitalService::getNameByKey($data['hospital_id'],''):'';
            return $data;
        });
    }







}